<?php if (!defined('CORE_DIR')) die('Wrong entry point!');

/* 
 * Copyright 2010 Anton Muraviev a.k.a kuromaisu
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */


Aero::define('RussianLocale', AS_SINGLETON);

/* -----------------------------------------------------------------------------
 * Class: RussianLocale
 * -----------------------------------------------------------------------------
 */
class RussianLocale extends AeroLocale
{
	protected $months = array(
		array('январь','января','январь','январю','январём','январе'),
		array('февраль','февраля','февраль','февралю','февралём','феврале'),
		array('март','марта','март','марту','мартом','марте'),
		array('апрель','апреля','апрель','апрелю','апрелем','апреле'),
		array('май','мая','май','маю','маем','мае'),
		array('июнь','июня','июнь','июню','июнем','июне'),
		array('июль','июля','июль','июлю','июлем','июле'),
		array('август','августа','август','августу','августом','августе'),
		array('сентябрь','сентября','сентябрь','сентябрю','сентябрём','сентябре'),
		array('октябрь','октября','октябрь','октябрю','октябрём','октябре'),
		array('ноябрь','ноября','ноябрь','ноябрю','ноябрём','ноябре'),
		array('декабрь','декабря','декабрь','декабрю','декабрём','декабре')
	);
	
	protected $weekdays = array(
		array('воскресенье','воскресенья','воскресенье','воскресенью','воскресеньем','воскресенье'),
		array('понедельник','понедельника','понедельник','понедельнику','понедельником','понедельнике'),
		array('вторник','вторника','вторник','вторнику','вторником','вторнике'),
		array('среда','среды','среду','среде','средой','среде'),
		array('четверг','четверга','четверг','четвергу','четвергом','четверге'),
		array('пятница','пятницы','пятницу','пятнице','пятницей','пятнице'),
		array('суббота','субботы','субботу','субботе','субботой','субботе')
	);
	
	public function inflect($number)
	{
		$rem = $number % 10;
		$number = $number % 100;
		
		if (($number < 10 || $number > 20) && $rem === 1)
		{
			$i = 1;
		}
		else if (($number < 10 || $number > 20) && (in_array($rem, array(2,3,4), true)))
		{
			$i = 2;
		}
		else
		{
			$i = 3;
		}
		
		return func_get_arg($i);
	}
	
	public function month($datetime, $form = 1)
	{
		$month = (int) $this->date($datetime,'n') - 1;
		
		if (isset($this->months[$month][$form]))
		{
			return $this->months[$month][$form];
		}
		
		return '';
	}

	public function weekday($datetime, $form = 0)
	{
		// TODO: check which is the first day of the week
		$weekday = (int) $this->date($datetime,'w');
		
		if (isset($this->weekdays[$weekday][$form]))
		{
			return $this->weekdays[$weekday][$form];
		}
		
		return '';
	}
	
	protected $magnitudes = array(
		array('тысяча','тысячи','тысяч'),
		array('миллион','миллиона','миллионов'),
		array('миллиард','миллиарда','миллиардов'),
		array('триллион','триллиона','триллионов'),
		array('квадриллион','квадриллиона','квадриллионов'),
		array('квинтиллион','квинтиллиона','квинтиллионов'),
		array('секстиллион','секстиллиона','секстиллионов'),
		array('септиллион','септиллиона','септиллионов'),
		array('октиллион','октиллиона','октиллионов'),
		array('нониллион','нониллиона','нониллионов'),
		array('дециллион','дециллиона','дециллионов'),
		array('дециллион','дециллиона','дециллионов'),
		array('ундециллион','ундециллиона','ундециллионов'),
		array('додециллион','додециллиона','додециллионов'),
		array('тредециллион','тредециллиона','тредециллионов')
	);
	
	protected $numbers = array(
		0 => '',
		1 => array('один','одна','одно'),
		2 => array('два','две','два'),
		3 => 'три',
		4 => 'четыре',
		5 => 'пять',
		6 => 'шесть',
		7 => 'семь',
		8 => 'восемь',
		9 => 'девять',
		10 => 'десять',
		11 => 'одинадцать',
		12 => 'двенадцать',
		13 => 'тринадцать',
		14 => 'четырнадцать',
		15 => 'пятнадцать',
		16 => 'шестнадцать',
		17 => 'семнадцать',
		18 => 'восемнадцать',
		19 => 'девятнадцать'
	);
	
	protected $decimals = array(
		0 => '',
		2 => 'двадцать',
		3 => 'тридцать',
		4 => 'сорок',
		5 => 'пятьдесят',
		6 => 'шестьдесят',
		7 => 'семьдесят',
		8 => 'восемьдесят',
		9 => 'девяносто',
	);
	
	protected $hundreds = array(
		1 => 'сто',
		2 => 'двести',
		3 => 'триста',
		4 => 'четыреста',
		5 => 'пятьсот',
		6 => 'шестьсот',
		7 => 'семьсот',
		8 => 'восемьсот',
		9 => 'девятьсот',
	);
	
	private $current_kind;
	
	public function spellout($number, $kind = 0)
	{
		if (!is_numeric($number) || empty($number))
		{
			return 'ноль';
		}
		
		$_kind = $this->current_kind;
		$this->current_kind = $kind;
		$result = $this->_spellout($number);
		$this->current_kind = $_kind;
		
		return implode(' ',$result);
	}
	
	protected function _spelloutMagnitude($integer, $power)
	{
		if (isset($this->magnitudes[$power-1]))
		{
			return ' '.call_user_func_array(array($this,'inflect'),array_merge(array($integer),$this->magnitudes[$power-1]));
		}
		
		return '';
	}
	
	protected function _spelloutHundreds($hundred, $power)
	{
		if ($hundred > 0)
		{
			return $this->hundreds[$hundred];
		}
	}
	
	protected function _spelloutDecimals($decimal, $power)
	{
		switch ($power)
		{
			case 0: $kind = $this->current_kind; break;
			case 1: $kind = 1; break;
			default:$kind = 0;
		}
		
		$string = '';
		
		$a10 = floor($decimal/10);
		$u10 = $decimal % 10;
		
		if ($a10 >= 2)
		{
			$string.= $this->decimals[$a10];
			
			if ($u10 > 0)
			{
				$string.= ' ' . (is_array($this->numbers[$u10]) ? $this->numbers[$u10][$kind] : $this->numbers[$u10]);
			}
		}
		else if ($u10 > 0 || $a10 > 0)
		{
			$i = $a10 * 10 + $u10;
			$string.= (is_array($this->numbers[$i]) ? $this->numbers[$i][$kind] : $this->numbers[$i]);
		}
		
		return $string;
	}
}
